package com.gjt.event;

import com.google.common.collect.Lists;
import org.springframework.util.CollectionUtils;

import javax.net.ssl.HandshakeCompletedEvent;
import javax.net.ssl.HandshakeCompletedListener;
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLSession;
import javax.security.cert.CertificateExpiredException;
import javax.security.cert.CertificateNotYetValidException;
import javax.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

public class CompleteConnectionEvent implements HandshakeCompletedListener {

    private static int isConnected = 0;

    public CompleteConnectionEvent(int isConnected) {
        this.isConnected = isConnected;
    }

    @Override
    public void handshakeCompleted(HandshakeCompletedEvent event) {
        System.out.println("握手结束");

        /**
         * 即密码组  TLS_AES_256_GCM_SHA384
         *  每个算法分4部分：协议，密钥，加密算法，校验和
         *  TLS：传输层安全协议
         *  AES_256_GCM：高级加密算法
         *  GCM：加密模式，结合了加密算法和认证机制
         *  SHA384：散列算法，用来计算摘要
         */
        System.out.println("加密套件为：" + event.getCipherSuite());

        //Session(1726829560947|TLS_AES_256_GCM_SHA384)
        System.out.println("会话为：" + event.getSession());

        // www.usps.com
        System.out.println("通信对方是：" + event.getSession().getPeerHost());

        isConnected = 1;

        /**
         *  会话管理
         *  1: 相同的会话中的不同的socket 使用一组相同的公开密钥和私有密钥,只有第一个Socket 需要生成和交换密钥的开销
         *  2: 禁止socket 之间的会话共享
         *  3: 方法
         */
        // 返回这个socket所属的session （会话）
        SSLSession session = event.getSession();

        System.out.println("session id: " + session.getId());
        System.out.println("sessionContext :" + session.getSessionContext());

        // 将时间戳转换为 Date 对象
        Date date = new Date(session.getCreationTime());
        Date lastAccessedTime = new Date(session.getLastAccessedTime());
        // 格式化日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String formattedDate = sdf.format(date);
        String formattedLastDate = sdf.format(lastAccessedTime);

        // 会话创建时间
        System.out.println("creationTime :" + formattedDate);
        // 最后访问时间
        System.out.println("lastAccessedTime :" + formattedLastDate);
        // 将会话作废
//        session.invalidate();

        // 设置信息
        session.putValue("Name", "gjt");

        // 获取信息
        System.out.println("session value :" + session.getValue("Name"));

        // 移出会话中的值
//        session.removeValue("Name");

        // 获取会话中的所有值的名字（可以理解成键）,并输出
        String[] valueNames = session.getValueNames();
        ArrayList<String> list = Lists.newArrayList(valueNames);
        list.forEach(System.out::println);

        try {
            // 一种接口，用于表示X X.509 v3 证书，定义了公共基础设施（PKI）中使用的数字证书格式
            X509Certificate[] peerCertificateChain = session.getPeerCertificateChain();


            if (null != peerCertificateChain) {
                ArrayList<X509Certificate> x509Certificates = Lists.newArrayList(peerCertificateChain);
                x509Certificates.forEach(e -> {
                    // 获取证书中的公钥
                    System.out.println("证书中的公钥:" + e.getPublicKey());

                    // 获取证书主体的Distinguished Name（DN）
                    System.out.println("证书主体的Distinguished Name:" + e.getSubjectDN());


                    // 获取证书生效日期
                    Date notBefore = e.getNotBefore();
                    String notBeforeStr = sdf.format(notBefore);
                    System.out.println("证书生效日期:" + notBeforeStr);

                    // 获取证书失效时间
                    Date notAfter = e.getNotAfter();
                    String notAfterStr = sdf.format(notAfter);
                    System.out.println("证书失效时间:" + notAfterStr);

                    // 检查当前日期是否在 证书有效期之间
                    try {
                        e.checkValidity(new Date());
                    } catch (CertificateExpiredException | CertificateNotYetValidException ex) {
                        throw new RuntimeException("前日期不在 证书有效期: " + ex);
                    }
                    ;


                });
            }
//            System.out.println("peerCertificateChain :" + peerCertificateChain.toString());
        } catch (SSLPeerUnverifiedException e) {
            throw new RuntimeException(e);
        }

        // 获取加密套件即使用的密码组
        String cipherSuite = session.getCipherSuite();
        System.out.println("加密套件使用的密码组:" + cipherSuite);

        System.out.println("对方的主机" + session.getPeerHost());



    }

    public static int getIsConnected() {
        return isConnected;
    }
}
